home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Developer Essentials / DTS Sample Code / System 7.0 Samples / CShell⁄THINK C / Print.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-20  |  8.0 KB  |  310 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** MultiFinder-Aware Shell Application
  5. **
  6. ** Program:     CShell
  7. ** File:        print.c
  8. ** Written by:  Eric Soldan
  9. ** Based on:    Code from Pete "Luke" Alexander.
  10. **
  11. ** Copyright © 1989-1991 Apple Computer, Inc.
  12. ** All rights reserved.
  13. */
  14.  
  15.  
  16.  
  17. /*****************************************************************************/
  18.  
  19.  
  20.  
  21. #include "CShell.h"                /* Get the CShell includes/typedefs, etc.    */
  22. #include "CShellCommon.h"        /* Get the stuff in common with rez.        */
  23. #include "CShell.protos"        /* Get the prototypes for CShell.            */
  24.  
  25. #ifndef __ERRORS__
  26. #include <Errors.h>
  27. #endif
  28.  
  29. #ifndef __RESOURCES__
  30. #include <Resources.h>
  31. #endif
  32.  
  33. #ifndef __UTILITIES__
  34. #include "Utilities.h"    /* 2/20/91 pvh - for QD macro */
  35. #endif
  36.  
  37.  
  38. /*****************************************************************************/
  39.  
  40.  
  41.  
  42. pascal void            PrintIdleProc(void);
  43. short                gPrintPage;
  44. static DialogPtr    PrintingStatusDialog;
  45.  
  46.  
  47.  
  48. /*****************************************************************************/
  49.  
  50.  
  51.  
  52. /* This print-loop function is designed to be called under various situations.
  53. ** The big issue that it handles is finder printing.  If multiple documents
  54. ** are to be printed from the finder, the user should only see one job dialog
  55. ** for all the files.  (If a job dialog is shown for each file, how does the
  56. ** user know for which file the dialog is for?)  So, for situations where
  57. ** there is more than one file to be printed, call this code the first time
  58. ** with the firstJob boolean true.  Normally, the jobDlg boolean will also
  59. ** be true, except that under 7.0, you may be printing in the background.
  60. ** If this is the case, you don't want a job dialog for even the first file,
  61. ** and you should pass in false for the jobDlg boolean in this case.  For
  62. ** files 2-N, you should pass false for both booleans.  For regular application
  63. ** printing, you should pass true for both booleans, since the file is the
  64. ** first (only) file, and you are not in the background.
  65. **
  66. ** After calling this function to print a document, you need to call it
  67. ** again with a nil document handle.  The print record for the first (or only)
  68. ** document printed is preserved in a static variable.  This is so that the
  69. ** job dialog information can be passed on to documents 2-N in the print job.
  70. ** Calling this function with the document handle nil tells this function
  71. ** that you are done printing documents, and that the print record for the
  72. ** first job can be disposed of.
  73. */
  74.  
  75. #pragma segment Print
  76. OSErr    AppPrintDocument(FileRecHndl frHndl, Boolean jobDlg, Boolean firstJob)
  77. {
  78.     OSErr            err;
  79.     THPrint            prRecHndl;
  80.     TPPrPort        printPort;
  81.     GrafPtr            oldPort;
  82.     short            i, keepResFile, fstPage, lstPage, copies;
  83.     TPrStatus        status;
  84.     ControlHandle    proceedButton;
  85.     Rect             rct;
  86.     
  87.     static THPrint    prMergeHndl;
  88.  
  89.     if (!frHndl) {
  90.         if (prMergeHndl) {
  91.             DisposHandle((Handle)prMergeHndl);
  92.             prMergeHndl = nil;
  93.         }
  94.         return(noErr);
  95.     }
  96.  
  97.     PrintingStatusDialog = nil;
  98.  
  99.     if (!(prRecHndl = (THPrint)NewHandle(sizeof(TPrint)))) return(memFullErr);
  100.         /* If we can't generate a print record handle, we are out of here. */
  101.  
  102.     BlockMove((Ptr)&((*frHndl)->doc.print), (Ptr)(*prRecHndl), sizeof(TPrint));
  103.         /* Get the document's print info into the print record handle. */
  104.  
  105.     GetPort(&oldPort);
  106.  
  107.     DoSetCursor(&QD(arrow));
  108.     PrOpen();
  109.     err = PrError();
  110.  
  111.     if (!err) {
  112.         keepResFile = CurResFile();
  113.  
  114.         if (!(*frHndl)->doc.printRecValid) {
  115.             PrintDefault(prRecHndl);            /* The document print record was never 
  116.             err = PrError();                    ** initialized.  Now is is. */
  117.         }            
  118.         if (!err) {
  119.             PrValidate(prRecHndl);        /* Do this just 'cause Apple says so. */
  120.             err = PrError();
  121.         }
  122.         if (!err) {
  123.             if (jobDlg) {                /* User gets to click some buttons. */
  124.                 if (!(PrJobDialog(prRecHndl))) err = userCanceledErr;
  125.                 else                           err = PrError();
  126.             }
  127.         }
  128.         if (!err) {
  129.             if (!firstJob) {
  130.                 PrJobMerge(prMergeHndl, prRecHndl);
  131.                 err = PrError();
  132.             }
  133.         }
  134.  
  135.         if (!err) {            /* Put the defaulted/validated/jobDlg'ed print record in the doc. */
  136.             fstPage  = (*prRecHndl)->prJob.iFstPage;
  137.             lstPage  = (*prRecHndl)->prJob.iLstPage;
  138.             copies   = (*prRecHndl)->prJob.iCopies;
  139.             BlockMove((Ptr)(*prRecHndl), (Ptr)&((*frHndl)->doc.print), sizeof(TPrint));
  140.             (*frHndl)->doc.printRecValid = true;
  141.  
  142.             ParamText((*frHndl)->fileState.fss.name, nil, nil, nil);
  143.             PrintingStatusDialog = GetNewDialog(rPrStatusDlg, nil, (WindowPtr)-1);
  144.             if (PrintingStatusDialog) {
  145.                 GetDItem(PrintingStatusDialog, 1, &i, (Handle *) &proceedButton, &rct);
  146.                 HiliteControl(proceedButton, 255);
  147.                     /* Setup the proceed/pause/cancel dialog with the document name. */
  148.                 (*prRecHndl)->prJob.pIdleProc = (PrIdleProcPtr) PrintIdleProc;
  149.                 UseResFile(keepResFile);
  150.                     /* Hook in the proceed/pause/cancel dialog. */
  151.             }
  152.  
  153.             for (i = 1; (i <= copies) && (!err); ++i) {
  154.  
  155.                 printPort = PrOpenDoc(prRecHndl, nil, nil);
  156.                 if (!(err = PrError())) {
  157.  
  158.                     gPrintPage = fstPage;
  159.                     while (gPrintPage <= lstPage) {
  160.  
  161.                         PrOpenPage(printPort, nil);
  162.  
  163.                         if (!(err = PrError()))
  164.                             ImageDocument(frHndl);
  165.                                 /* Do the print thing here. */
  166.  
  167.                         PrClosePage(printPort);
  168.  
  169.                         if (!gPrintPage) break;
  170.                         ++gPrintPage;
  171.                     }
  172.                     gPrintPage = 0;
  173.                     PrCloseDoc(printPort);
  174.                 }
  175.             }
  176.         }
  177.  
  178.         if (
  179.             (!err) &&
  180.             ((*prRecHndl)->prJob.bJDocLoop == bSpoolLoop) &&
  181.             (!(err = PrError()))
  182.         ) {
  183.             PrPicFile(prRecHndl, nil, nil, nil, &status);
  184.             err = PrError();
  185.         }
  186.     }
  187.  
  188.     if (firstJob) prMergeHndl = prRecHndl;
  189.     else          DisposHandle((Handle)prRecHndl);
  190.  
  191.     if (PrintingStatusDialog) DisposDialog(PrintingStatusDialog);
  192.  
  193.     PrClose();
  194.     SetPort(oldPort);
  195.  
  196.     return(err);
  197. }
  198.  
  199.  
  200.  
  201. /*****************************************************************************/
  202.  
  203.  
  204.  
  205. /* PrintIdleProc will handle events in the 'Printing Status Dialog' which
  206. ** gives the user the option to 'Proceed', 'Pause', or 'Cancel' the current
  207. ** printing job during print time.
  208. **
  209. ** The buttons:
  210. **        1: Proceed
  211. **        2: Pause
  212. **        3: Cancel 
  213. */
  214.  
  215. #pragma segment Print
  216. pascal void        PrintIdleProc(void)
  217. {
  218.     Boolean                button, paused;
  219.     ControlHandle        pauseButton, proceedButton;
  220.     DialogPtr            aDialog;
  221.     EventRecord            anEvent;
  222.     GrafPtr                oldPort;
  223.     Rect                 rct;
  224.     short                item, itemType, keepResFile;
  225.  
  226.     GetPort(&oldPort);
  227.  
  228.     UseResFile(keepResFile = CurResFile());
  229.  
  230.     GetDItem(PrintingStatusDialog, 1, &itemType, (Handle *) &proceedButton, &rct);
  231.     HiliteControl(proceedButton, 255);
  232.     GetDItem(PrintingStatusDialog, 2, &itemType, (Handle *) &pauseButton, &rct);
  233.  
  234.     paused = false;
  235.     do {
  236.         if (GetNextEvent((mDownMask + mUpMask + updateMask), &anEvent)) {
  237.             if (PrintingStatusDialog != FrontWindow ())
  238.             SelectWindow(PrintingStatusDialog);
  239.  
  240.             if (IsDialogEvent(&anEvent)) {
  241.                 button = DialogSelect(&anEvent, &aDialog, &item);
  242.  
  243.                 if ((button) && (aDialog == PrintingStatusDialog)) {
  244.                     switch (item) {
  245.                         case 1:
  246.                             HiliteControl(pauseButton, 0);        /* Enable PAUSE    */
  247.                             HiliteControl(proceedButton, 255);    /* Disable PROCEED */
  248.                             paused = false;
  249.                             break;
  250.                         case 2:
  251.                             HiliteControl(pauseButton, 255);    /* Disable PAUSE  */
  252.                             HiliteControl(proceedButton, 0);    /* Enable PROCEED */
  253.                             paused = true;
  254.                             break;
  255.                         case 3:
  256.                             PrSetError(iPrAbort);               /* CANCEL printing */
  257.                             paused = false;
  258.                             break;
  259.                     }
  260.                 }
  261.             }
  262.         }
  263.     } while (paused != false); 
  264.  
  265.     SetPort(oldPort);
  266. }
  267.  
  268.  
  269.  
  270. /*****************************************************************************/
  271.  
  272.  
  273.  
  274. #pragma segment Print
  275. OSErr    PresentStyleDialog(FileRecHndl frHndl)
  276. {
  277.     OSErr        err;
  278.     THPrint        prRecHndl;
  279.  
  280.     if (!(prRecHndl = (THPrint)NewHandle(sizeof(TPrint))))
  281.         return(memFullErr);
  282.  
  283.     PrOpen();
  284.  
  285.     if (!(err = PrError())) {
  286.  
  287.         BlockMove((Ptr)&(*frHndl)->doc.print, (Ptr)*prRecHndl, sizeof(TPrint));
  288.             /* Get data, valid or not. */
  289.  
  290.         if (!(*frHndl)->doc.printRecValid) PrintDefault(prRecHndl);
  291.         else                                PrValidate(prRecHndl);
  292.         if (!(err = PrError())) {
  293.             if (PrStlDialog(prRecHndl)) {
  294.                 BlockMove((Ptr)*prRecHndl, (Ptr)&(*frHndl)->doc.print, sizeof(TPrint));
  295.                 (*frHndl)->doc.printRecValid  = true;
  296.                 (*frHndl)->fileState.docDirty = true;
  297.             }
  298.             else err = userCanceledErr;
  299.         }
  300.     }
  301.  
  302.     DisposHandle((Handle)prRecHndl);
  303.     PrClose();
  304.  
  305.     return(err);
  306. }
  307.  
  308.  
  309.  
  310.